#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

using namespace std;

// #define MySelf 1

const string blank_space_sep = " ";
const string protocal_sep = "\n";

string Encode(string &s)
{
    string pakg = to_string(s.size());
    pakg += protocal_sep;
    pakg += s;
    pakg += protocal_sep;
    return pakg;
}

// len"\n"x op y\n
bool Decode(string &pakg, string *s)
{
    auto pos = pakg.find(protocal_sep);
    if (pos == string::npos)
        return false;

    string len_str = pakg.substr(0, pos);
    int len = stoi(len_str);
    int total_len = len + len_str.size() + 2;
    if (total_len > pakg.size())
        return false;

    *s = pakg.substr(pos + 1, len);
    // erase 移除报文 pakg.erase(0,total_len)
    pakg.erase(0, total_len);
    return true;
}

class Request
{
public:
    Request() {}
    Request(int d1, int d2, char oper) : x(d1), y(d2), op(oper)
    {
    }

public:
    bool Serialize(string *out)
    {
#ifdef MySelf
        // struct=>string ("有效载荷长度"\n"x op y")
        // 有效载荷
        string s = to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += to_string(y);

        *out = s;
        return true;

#else // 条件编译
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }

    bool Deserialize(const string &in) //"x op y"
    {
#ifdef MySelf
        auto l = in.find(blank_space_sep);
        if (l == string::npos)
            return false;
        string part_x = in.substr(0, l);

        size_t r = in.rfind(blank_space_sep);
        if (r == string::npos)
            return false;
        string part_y = in.substr(r + 1);

        if (l + 2 != r)
            return false;
        op = in[l + 1];
        x = stoi(part_x);
        y = stoi(part_y);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        cout << "新请求构建完成： " << x << op << y << endl;
    }

public:
    int x;
    int y;
    char op; // + - * / %
};

// json,protobuf

class Response
{
public:
    Response() {}
    Response(int res, int c) : result(res), code(c)
    {
    }

public:
    bool Serialize(string *out)
    {
#ifdef MySelf
        //"有效载荷长度"\n"result code"
        // 有效载荷
        string s = to_string(result);
        s += blank_space_sep;
        s += to_string(code);

        *out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        Json::StyledWriter w;
        // Json::FastWriter w;
        *out=w.write(root);
        
        return true;
#endif
    }
    bool Deserialize(const string &in)
    {
#ifdef MySelf
        // result code
        auto pos = in.find(blank_space_sep);
        if (pos == string::npos)
            return false;

        string l = in.substr(0, pos);
        string r = in.substr(pos + 1);

        result = stoi(l);
        code = stoi(r);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        result = root["result"].asInt();
        code = root["code"].asInt();
        return true;
#endif
    }

    void DebugPrint()
    {
        cout << "结果响应完成,result: " << result << ",code: " << code << endl;
    }

public:
    int result;
    int code; // 0表示可信 !0具体是几表示对应的错误原因
};